function processFrames(segFunct, wormVideo, startFrame, endFrame, frameRate)

 warning('off', 'images:initSize:adjustingMag');
 warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');
 
global dataList
global suppData


curTime = 0;
frameOffsetRow = 0;
frameOffsetCol = 0;
iDatarow = 0; 

nFrames = endFrame; 
cumDist = 0;
 instantVelocity = 0;
 initCentroidRow = 0;
 initCentroidCol = 0;
 prevCentroidRow = 0;
 prevCentroidCol = 0;
 prevTime = 0;
 range = 0;
 prevInstantVelocity = 0;
 
for iFrame=startFrame:nFrames
    
    %Keeps track of the rows in the data, not the frames that are processed
    iDatarow = iDatarow + 1;
    
     try
        disp(iDatarow);

        frameGrab = wormVideo(iFrame).gdata;
      
        
        suppData(iDatarow).SeqNum = iDatarow;
        suppData(iDatarow).FrameNum = iFrame;
        suppData(iDatarow).GrayScaleImage = frameGrab;
        dataList(iDatarow).SeqNum = iDatarow; 
        dataList(iDatarow).FrameNum = iFrame;
        [numRows, numCols ] = size(frameGrab);
        dataList(iDatarow).FrameRows = numRows;
        dataList(iDatarow).FrameCols = numCols;
        
        dataList(iDatarow).FrameOffsetRow = frameOffsetRow;       %Frame Offset Row
        dataList(iDatarow).FrameOffsetCol  = frameOffsetCol;      %Frame Offset Col
        
       
        
        %% Current time 
        dataList(iDatarow).CurTime = frameRate*(iFrame - startFrame+1);                

        %% Calculate delta time     
        if prevTime == 0
            dataList(iDatarow).DeltaTime = 0;
        else
            dataList(iDatarow).DeltaTime =  dataList(iDatarow).CurTime - prevTime;
        end

        %% Elapsed Time
        if prevTime == 0
            dataList(iDatarow).ElapsedTime = 0;
        else
            dataList(iDatarow).ElapsedTime = prevTime + dataList(iDatarow).DeltaTime;
        end
        
        %% Segmentation
        
        %Segment the image and get black and white frame
        bwImage = segFunct(frameGrab);
        
        
        
        suppData(iDatarow).BwImage = bwImage;  
        
        %% BW Shape and Size
        
        regionStats = getBwShapeAndSize(bwImage);
        dataList(iDatarow).Area = regionStats.Area;
        dataList(iDatarow).CentroidRow = round(regionStats.Centroid(2));
        dataList(iDatarow).CentroidCol = round(regionStats.Centroid(1));
        if initCentroidRow == 0 || initCentroidCol == 0
            initCentroidRow = dataList(iDatarow).CentroidRow ;
            initCentroidCol = dataList(iDatarow).CentroidCol;
        end
        dataList(iDatarow).MajorAxisLength = regionStats.MajorAxisLength;
        dataList(iDatarow).MinorAxisLength = regionStats.MinorAxisLength;
        dataList(iDatarow).Elongation = regionStats.Elongation;
        dataList(iDatarow).ComptFactor = regionStats.ComptFactor;
        dataList(iDatarow).Heywood = regionStats.Heywood;
        dataList(iDatarow).Hydraulic = regionStats.Hydraulic; 
        dataList(iDatarow).RectBigSide = regionStats.RectBigSide;
        dataList(iDatarow).RectRatio = regionStats.RectRatio;
        dataList(iDatarow).Ixx = regionStats.Ixx;
        dataList(iDatarow).Iyy = regionStats.Iyy;
        dataList(iDatarow).Ixy = regionStats.Ixy;
        dataList(iDatarow).MaxWidth = regionStats.MaxWidth;
        suppData(iDatarow).DistTransform = regionStats.DistTransform;
 
        %% Get Endpoint Information

        %Determine from the segmetnation whether it is a loop or not
        dataList(iDatarow).IsLoop = isLoop(bwImage);
        
        %Determine from the curvature what the endpoints are
        kernelRadius = 10;
        sigma = 1;
        threshold = 0.6;
        sigmaAdjusted = 1;
        [endpointsFromCurvature, ~] =  getEndpointsFromCurvature(bwImage, kernelRadius, sigma, threshold, sigmaAdjusted);
        
        if isempty(endpointsFromCurvature)
             dataList(iDatarow).NumEndsVisible = 0;
        else
            dataList(iDatarow).NumEndsVisible = size(endpointsFromCurvature,1);
        end
       if dataList(iDatarow).NumEndsVisible == 0
            dataList(iDatarow).Curv_EndARow = 1;
            dataList(iDatarow).Curv_EndACol = 1;
            dataList(iDatarow).Curv_EndBRow = 1;
            dataList(iDatarow).Curv_EndBCol = 1;
        elseif dataList(iDatarow).NumEndsVisible == 1
            dataList(iDatarow).Curv_EndARow = endpointsFromCurvature(1,1);
            dataList(iDatarow).Curv_EndACol = endpointsFromCurvature(1,2);
            dataList(iDatarow).Curv_EndBRow = 1;
            dataList(iDatarow).Curv_EndBCol = 1;
        elseif dataList(iDatarow).NumEndsVisible == 2
            dataList(iDatarow).Curv_EndARow = endpointsFromCurvature(1,1);
            dataList(iDatarow).Curv_EndACol = endpointsFromCurvature(1,2);
            dataList(iDatarow).Curv_EndBRow = endpointsFromCurvature(2,1);
            dataList(iDatarow).Curv_EndBCol = endpointsFromCurvature(2,2);
        end
       
                
        %% Skeleton Image
        if dataList(iDatarow).IsLoop == 1;
            bwImageMod = keepOnlyLargestHole(bwImage);
            if dataList(iDatarow).NumEndsVisible > 2
                skeleton = getSkelImage(bwImageMod, 2);
            else
                skeleton = getSkelImage(bwImageMod, dataList(iDatarow).NumEndsVisible);
            end
        else
             skeleton = getSkelImage(bwImage, 2);
        end
        
        suppData(iDatarow).SkelImage = skeleton;

        %% Determine posture 
        
        %postureSkel = getPostureFromSkel(skeleton);
        %postureMovement = getPostureFromMovement(dataList, iDatarow);
        posture = getPostureFromSkewer(dataList, iDatarow);
        
        dataList(iDatarow).Posture = posture; 
        
                
        %% Skeleton Points (sktp)

         %Get a list of subscripts for all pixels in the skeleton
         try
             sktpAll = getSkelPixels(skeleton, posture);
             suppData(iDatarow).SktpAll  = sktpAll;
             dataList(iDatarow).Sktp_EndARow = sktpAll(1,1);
             dataList(iDatarow).Sktp_EndACol = sktpAll(1,2);
             dataList(iDatarow).Sktp_EndBRow = sktpAll(size(sktpAll,1),1);
             dataList(iDatarow).Sktp_EndBCol = sktpAll(size(sktpAll,1),2);
         catch e
           
             dataList(iDatarow).Sktp_EndARow = 0;
             dataList(iDatarow).Sktp_EndACol = 0;
             dataList(iDatarow).Sktp_EndBRow = 0;
             dataList(iDatarow).Sktp_EndBCol = 0;
         end
            
     
         
        %% Check head and tail 

       try
        
            result = checkHTFromSkewer(dataList,iDatarow, numRows);
           if result == 0
               sktpAll = reverserows(sktpAll);
           end
       catch
           
       end
%             kernelRadius = 10;
%             distTransform = suppData(iDatarow).DistTransform;
%             if iDatarow == 1 
%                 prevSkewerAngle = 400;
%             else
%                prevSkewerAngle =  dataList(iDatarow-1).SkewerAngle;
%             end
%             
%             results = checkHeadAndTail(frameGrab, bwImage,sktpAll, kernelRadius,distTransform, prevSkewerAngle);
%             dataList(iDatarow).CurvDiff = results.CurvDiff;
%             dataList(iDatarow).SkewerCurv = results.SkewerCurv;
%             dataList(iDatarow).IntensityDiff  = results.IntensityDiff;
%             dataList(iDatarow).SkewerIntensity = results.SkewerIntensity;  
%             dataList(iDatarow).WidthProfileDiff =  results.WidthProfileDiff;
%             dataList(iDatarow).SkewerWidth =  results.SkewerWidth;
%             dataList(iDatarow).SkewerAngleDiff = results.SkewerAngleDiff;
%             dataList(iDatarow).SkewerPriorMatch = results.SkewerPriorMatch;
%             dataList(iDatarow).Winner = results.Winner;
%             if results.Winner == 2
%                  sktpAll = reverserows(sktpAll);
%             end
%% Assign head and tail
        try
            dataList(iDatarow).HeadRow = sktpAll(1,1);
            dataList(iDatarow).HeadCol = sktpAll(1,2);
            dataList(iDatarow).TailRow = sktpAll(size(sktpAll,1),1);
            dataList(iDatarow).TailCol = sktpAll(size(sktpAll,1),2);
        catch
            
            dataList(iDatarow).HeadRow = 0;
            dataList(iDatarow).HeadCol = 0;
            dataList(iDatarow).TailRow = 0;
            dataList(iDatarow).TailCol = 0;
%             
       end
       
       
      
       
        %% Get skeleton shape and size features
        
        try
            dataList(iDatarow).TrailPointRow = sktpAll(7,1);
            dataList(iDatarow).TrailPointCol = sktpAll(7,2);
            skelStats = getSkelShapeAndSize(dataList(iDatarow).Area, suppData(iDatarow).DistTransform, skeleton, sktpAll);
            dataList(iDatarow).Thickness = skelStats.Thickness;
            dataList(iDatarow).Fatness = skelStats.Fatness;
            dataList(iDatarow).SkelNumOfPixels = skelStats.SkelNumOfPixels;
            dataList(iDatarow).Length = skelStats.Length;
            dataList(iDatarow).LengthToPixels = skelStats.LengthToPixels;
        catch
            
            dataList(iDatarow).TrailPointRow = 0;
            dataList(iDatarow).TrailPointCol = 0;
            dataList(iDatarow).Thickness =0;
            dataList(iDatarow).Fatness = 0;
            dataList(iDatarow).SkelNumOfPixels = 0;
            dataList(iDatarow).Length = 0;
            dataList(iDatarow).LengthToPixels = 0;
                   
        end
        
        
        %% Get information about the skeleton bends

        %Break the skeleton into 5-pixel long sections
        %numPoints = floor(frameProps.SkelNumOfPixels/5)+ 1; 
       try
            numPoints = 13;
            [  sktp13, ~] = createSktp(sktpAll, numPoints);
            suppData(iDatarow).Sktp13 = sktp13;
            STATS = getBendingStats(sktp13);
            dataList(iDatarow).SktvAglAve =  STATS.SktvAglAve;
            dataList(iDatarow).SktvDisAveToLength = STATS.SktvDisAve/dataList(iDatarow).Length;
            dataList(iDatarow).SktvDisMaxToLength =  STATS.SktvDisMax/dataList(iDatarow).Length;
            dataList(iDatarow).SktvDisMinToLength = STATS.SktvDisMin/dataList(iDatarow).Length;
            dataList(iDatarow).SktvAglMax =  STATS.SktvAglMax;
       catch
            dataList(iDatarow).SktvAglAve =  0;
            dataList(iDatarow).SktvDisAveToLength = 0;
            dataList(iDatarow).SktvDisMaxToLength =  0;
            dataList(iDatarow).SktvDisMinToLength = 0;
            dataList(iDatarow).SktvAglMax = 0;
       end        
            
       
    
        %% SKEWER sktp analysis 

       try
            [ skewerStats] = getSkewerStats(sktpAll, dataList(iDatarow).Length, size(frameGrab, 1));
            dataList(iDatarow).SkewerAngle = skewerStats.SkewerAngle;
            dataList(iDatarow).SktHeight = skewerStats.SktHeight ;
            dataList(iDatarow).SktWidth = skewerStats.SktWidth ;
            dataList(iDatarow).SktAmpRatio = skewerStats.SktAmpRatio ;
            dataList(iDatarow).SktCmptFactor = skewerStats.SktCmptFactor;
            dataList(iDatarow).SktElgFactor = skewerStats.SktElgFactor;
            dataList(iDatarow).SktIxx = skewerStats.Ixx;
            dataList(iDatarow).SktIyy = skewerStats.Iyy;
            dataList(iDatarow).SktAglAve =skewerStats.SktAglAve;
            dataList(iDatarow).Xsym =skewerStats.Xsym;
            dataList(iDatarow).Ysym = skewerStats.Ysym;
            dataList(iDatarow).XYsym = skewerStats.XYsym;
            dataList(iDatarow).TrackAmplitude = skewerStats.TrackAmplitude;
            dataList(iDatarow).TrackPeriod = skewerStats.TrackPeriod;
       catch
            
            dataList(iDatarow).SkewerAngle = 0;
            dataList(iDatarow).SktHeight = 0;
            dataList(iDatarow).SktWidth = 0;
            dataList(iDatarow).SktAmpRatio = 0 ;
            dataList(iDatarow).SktCmptFactor = 0;
            dataList(iDatarow).SktElgFactor = 0;
            dataList(iDatarow).SktIxx = 0;
            dataList(iDatarow).SktIyy = 0;
            dataList(iDatarow).SktAglAve = 0;
            dataList(iDatarow).Xsym =0;
            dataList(iDatarow).Ysym = 0;
            dataList(iDatarow).XYsym = 0;
            dataList(iDatarow).TrackAmplitude =0;
            dataList(iDatarow).TrackPeriod = 0;
        
       end
            
       
        %% Delta x
        if prevCentroidCol == 0 
           dataList(iDatarow).DeltaX = 0;
        else
           dataList(iDatarow).DeltaX = prevCentroidCol - dataList(iDatarow).CentroidCol;
        end

        %% Delta y
        if prevCentroidRow == 0
           dataList(iDatarow).DeltaY = 0;
        else
           dataList(iDatarow).DeltaY ...
               = prevCentroidRow - dataList(iDatarow).CentroidRow;
        end

         %% Delta Distance 
        if prevCentroidRow == 0 || prevCentroidCol == 0
           dataList(iDatarow).DeltaDist = 0;
        else
           dataList(iDatarow).DeltaDist ...
               = norm( [prevCentroidCol - dataList(iDatarow).CentroidCol,...
                        prevCentroidRow - dataList(iDatarow).CentroidRow]);
        end   
        
        %% Velocity Vector Angle
        if prevCentroidCol == 0
            dataList(iDatarow).VectorAngle = 0;
        else
            dataList(iDatarow).VectorAngle = acos(( dataList(iDatarow).CentroidCol - prevCentroidCol) /dataList(iDatarow).DeltaDist);
        end

        %% Intantaneous velocity          
        instantVelocity = dataList(iDatarow).DeltaDist /dataList(iDatarow).DeltaTime;
        dataList(iDatarow).InstantVelocity = instantVelocity;
        

        %% Instantaneous acceleration
        if iDatarow == 1
            dataList(iDatarow).InstantAccel = 0;
        else
            deltaVel = dataList(iDatarow).InstantVelocity -  prevInstantVelocity;
            dataList(iDatarow).InstantAccel = deltaVel/dataList(iDatarow).DeltaTime;
        end

        %% Total distance travelled
         cumDist = cumDist +   dataList(iDatarow).DeltaDist;     
         dataList(iDatarow).CumDist =  cumDist;
        

        %% Range
         if prevCentroidRow == 0 && prevCentroidCol == 0
             dataList(iDatarow).Range = 0;
         else
             dataList(iDatarow).Range =norm( [initCentroidCol - dataList(iDatarow).CentroidCol,...
                        initCentroidRow - dataList(iDatarow).CentroidRow]);
         end
         
         %% Is reversal frame? 
         try
             dataList(iDatarow).IsReversal = isReversal(suppData(iDatarow-1).SktpAll,...
                                                 suppData(iDatarow).SktpAll,...
                                                 dataList(iDatarow).Length,...
                                                 dataList(iDatarow-1).SkewerAngle,...
                                                 dataList(iDatarow).SkewerAngle );
         catch
            dataList(iDatarow).IsReversal = 0;
         end
         
         prevCentroidRow = dataList(iDatarow).CentroidRow;
         prevCentroidCol = dataList(iDatarow).CentroidCol;
         prevTime = dataList(iDatarow).CurTime;
         prevInstantVelocity = dataList(iDatarow).InstantVelocity;
         
   catch ME
        
        msgString = getReport(ME);
        disp(ME.stack);
        disp(msgString);
               
        dataList = fillMissingValues( iDatarow, dataList, 1);
        suppData = fillMissingValues( iDatarow, suppData, []);
              
        
        continue;
    end
    end 
end%function